home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’96
/
TrimScreen
/
TrimScreen.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-06-21
|
3KB
|
92 lines
#include <Palettes.h>
#include <LoMem.h>
#include <StuTypes.h>
#pragma parameter __A0 RegA5() // MOVEA.L A5,A0
local Handle RegA5(void) = { 0x204D };
typedef struct { short number; Rect r[]; } nrct;
typedef struct { Ptr baseAddr; short rowBytes; long topleft; long botright; } BMTemplate;
void fix_bitmap(BitMap *bm, Ptr newbase, short newright);
void fix_grafport(GrafPtr gp, Ptr newbase, short newright);
export void main(void)
{
QDGlobals *qdglobptr = (QDGlobals *)(*RegA5() - sizeof(QDGlobals) + sizeof(GrafPtr));
nrct **rh = (nrct **)GetResource('nrct', 0); // Read configuration
GDPtr gdevp = GetMainDevice()[0]; // Get the main screen device
PixMapPtr pm = gdevp->gdPMap[0]; // And get its pixmap
// Decide what multiple to round pixel count to (to preserve byte alignment)
short pixel_mask = (pm->pixelSize >= 8) ? 0 : (8 / pm->pixelSize - 1);
// pixels cut from left edge
short trim_l = (rh[0]->r[0].left + pixel_mask) & ~pixel_mask;
short pixels_cut = trim_l + rh[0]->r[0].right; // Total pixels cut
long byte_shift = trim_l * pm->pixelSize / 8; // Offset to add to baseAddr
Ptr newbase = pm->baseAddr + byte_shift;
short newright = pm->bounds.right - pixels_cut;
WindowPeek wp = WindowList;
register BMTemplate *bm = NULL;
register Ptr oldbase = pm->baseAddr;
register long oldtopleft = *(long*)(&pm->bounds.top);
register long oldbotright = *(long*)(&pm->bounds.bottom);
//Debugger();
ScrnBase = newbase; // Update the ScrnBase lomem variable
gdevp->gdRect.right = newright; // Fix the gdRect of the main device
CrsrPin.right = newright; // Update the cursor limit rect
// If an A5 world is set up, fix the screenBits variable
if (qdglobptr->screenBits.baseAddr == pm->baseAddr)
fix_bitmap(&qdglobptr->screenBits, newbase, newright);
fix_bitmap((BitMap*)pm, newbase, newright); // Fix the main device's pixmap
fix_grafport(WMgrPort, newbase, newright); // Fix the window manager (desktop) ports
fix_grafport((GrafPtr)WMgrCPort, newbase, newright);
while (wp) // Fix any open windows
{
fix_grafport(&wp->port, newbase, newright);
wp=wp->nextWindow;
}
// Damn! After all this, it still doesn't work. Do an exhaustive search of all
// memory, finding all BitMaps which look like copies of screenBits, and fix them.
while ((Ptr)bm < BufPtr)
{
if (bm->baseAddr == oldbase &&
bm->topleft == oldtopleft &&
bm->botright == oldbotright)
fix_bitmap((BitMap *)bm, newbase, newright);
bm = (BMTemplate*)((Ptr)bm+2);
}
{
int i = 0;
long rowbytes = pm->rowBytes & 0x3FFF;
Ptr p = oldbase;
while (i<pm->bounds.bottom)
{
int j;
Ptr pp = p;
for (j=0; j<byte_shift; j++) *pp++ = 0xFF;
p += rowbytes;
i++;
}
}
}
void fix_bitmap(BitMap *bm, Ptr newbase, short newright)
{
// Check if this is actually the PixMapHandle of a CGrafPort
if ((bm->rowBytes & 0xC000) == 0xC000) bm = (BitMap *)*(bm->baseAddr);
bm->baseAddr = newbase;
bm->bounds.right = newright;
}
void fix_grafport(GrafPtr gp, Ptr newbase, short newright)
{
fix_bitmap(&gp->portBits, newbase, newright);
gp->portRect.right = newright;
}